package com.orange.delivery.spring.security;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public class CustomUserDetailsService implements UserDetailsService {

	private static final String ROLES_HEADER = "ftapplicationroles";
	private static final String ROLE_PREFIX = "ROLE_";

	private static final Logger LOG = LoggerFactory.getLogger(CustomUserDetailsService.class.getName());

	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		LOG.info("gassi username received : {}", username);

		// If needed, validate username here

		// Get the user roles from Gassi and set them to Spring Security
		Collection<SimpleGrantedAuthority> rolesSpringSecurity = new ArrayList<SimpleGrantedAuthority>();
		// Http request is provided through a filter. See requestContextFilter Spring Bean
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
		if (request != null) {
			String rolesInHeader = request.getHeader(ROLES_HEADER);
			LOG.debug("gassi roles received : {}", rolesInHeader);
			if (rolesInHeader != null) {
				// Role format : "<basicat>-<version><phase>
				// <role1>[,<basicat>-<version><phase> <role2>]
				Collection<String> rolesInHeaderList = Arrays.asList(rolesInHeader.split("\\s*,\\s*"));
				int space;
				String role;
				for (String prefixAndRole : rolesInHeaderList) {
					space = prefixAndRole.indexOf(" ");
					if (space >= 0) {
						// normal case
						role = prefixAndRole.substring(space + 1);
					} else {
						role = prefixAndRole;
					}
					// Add "ROLE_" if needed, so that it conforms to Spring Security
					if (role.startsWith(ROLE_PREFIX)) {
						rolesSpringSecurity.add(new SimpleGrantedAuthority(role));
					} else {
						rolesSpringSecurity.add(new SimpleGrantedAuthority(ROLE_PREFIX + role));
					}
				}
			}
		}

		UserDetails user = new User(username, "password", true, true, true, true, rolesSpringSecurity);

		return user;
	}
}